# 导入Streamlit库，用于创建Web应用界面
import streamlit as st
# 从openai库导入OpenAI客户端，用于调用大模型API
from openai import OpenAI
# 导入os库，用于处理操作系统相关的功能（虽然此处未直接使用）
import os

# 设置网页标题为“聊天机器人”
st.title("聊天机器人")

# 在侧边栏中组织设置选项
with st.sidebar:
    # 在侧边栏中添加一个标题“设置参数”
    st.header("设置参数")
    # （注释掉的代码，原为子标题，效果与header类似）

    # 创建一个密码输入框，用于用户输入API密钥，输入内容会被隐藏
    api_key = st.text_input("请输入你的API_KEY", type="password")

    # 创建一个滑动条，用于选择生成文本的“温度”值
    # 范围从0.0到2.0，默认值为0.9
    # 温度值越高，生成内容越随机、有创造性；越低则越确定、保守
    temperature = st.slider("温度值", 0.0, 2.0, 0.9)

# 检查用户是否已经输入了API密钥
if not api_key:
    # 如果没有输入API密钥，则显示错误信息
    st.error("请输入你的API_KEY来开始聊天！")
    # 并停止应用执行，直到用户提供密钥
    st.stop()

# 初始化对话历史（用于多轮对话）
# 检查session_state中是否存在"messages"变量
# 如果不存在（即首次运行或新会话），则初始化一个包含系统消息的列表
if "messages" not in st.session_state:
    st.session_state["messages"] = [
        {"role": "system", "content": "You are a helpful assistant."}  # 系统设定：助手角色
    ]

# 创建一个容器用于显示聊天消息
messages = st.container()

# 遍历session_state中存储的所有消息
for item in st.session_state.messages:
    # 如果消息角色是用户（user），则以用户消息的样式显示内容
    if item["role"] == "user":
        messages.chat_message("user").write(item["content"])
    # 如果消息角色是助手（assistant），则以AI消息的样式显示内容
    if item["role"] == "assistant":
        messages.chat_message("assistant").write(item["content"])

# 检查用户是否在聊天输入框中提交了新消息
# := 是海象运算符，用于在条件判断中同时赋值
if prompt := st.chat_input("请输入..."):
    # 将用户的输入以用户消息的样式显示在聊天界面中
    messages.chat_message("user").write(prompt)

    # 创建OpenAI兼容的客户端实例，用于调用大模型API
    client = OpenAI(
        base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",  # 指定API的基础URL（这里是阿里云通义千问）
        api_key=api_key  # 使用用户输入的API密钥进行认证
    )

    # 将用户的当前输入添加到对话历史中
    st.session_state.messages.append(
        {"role": "user", "content": prompt}
    )
    
    # 调用大模型的聊天补全接口，生成回复
    response = client.chat.completions.create(
        model="qwen-plus",                    # 指定使用的模型为 qwen-plus
        messages=st.session_state.messages,   # 传入完整的对话历史
        temperature=temperature,              # 使用用户在侧边栏选择的温度值
        stream=True                           # 启用流式传输，逐字生成回复，提升用户体验
    )

    # 将模型的流式响应实时显示在聊天界面中，并收集完整回复内容
    full_content = messages.chat_message("ai").write_stream(response)

    # 将模型生成的完整回复内容添加到对话历史中，以便后续对话使用
    st.session_state.messages.append(
        {"role": "assistant", "content": full_content}
    )
